package middleware

import (
	"encoding/gob"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"strings"
	"time"
	"webook/internal/web"
)

type LoginJwtMiddlewareBuilder struct {
	paths []string
}

func NewLoginJwtMiddlewareBuilder() *LoginJwtMiddlewareBuilder {
	return &LoginJwtMiddlewareBuilder{}
}

// IgnorePaths 设置需要忽略登录校验的路径
// path: 需要忽略登录校验的路径
// 返回值: *LoginMiddlewareBuilder - 返回中间件构建器自身，支持链式调用
func (l *LoginJwtMiddlewareBuilder) IgnorePaths(path string) *LoginJwtMiddlewareBuilder {
	l.paths = append(l.paths, path)
	return l
}

// Build 构建登录中间件处理函数
// context: Gin框架的上下文对象
// 返回值: gin.HandlerFunc - Gin框架的处理函数，用于拦截未登录用户的请求
func (l *LoginJwtMiddlewareBuilder) Build() gin.HandlerFunc {
	gob.Register(time.Now())
	return func(context *gin.Context) {
		// 允许访问登录和注册页面，无需登录检查

		for _, path := range l.paths {
			if context.Request.URL.Path == path {
				return
			}
		}

		tokenHeader := context.GetHeader("Authorization")
		if tokenHeader == "" {
			context.JSON(401, gin.H{
				"message": "请先登录",
			})
			context.Abort()
			return
		}
		segs := strings.Split(tokenHeader, " ")
		if len(segs) != 2 {
			context.JSON(401, gin.H{
				"message": "请先登录",
			})
			context.Abort()
			return
		}
		tokenStr := segs[1]
		claims := &web.UserClaims{}
		token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
			return []byte("dlfkhjkdlhjkdgh"), nil
		})
		if err != nil {
			context.JSON(401, gin.H{
				"message": "请先登录",
			})
			context.Abort()
			return
		}
		// err为nil，token不为nil
		if token == nil || !token.Valid || claims.UserId == 0 {
			context.JSON(401, gin.H{
				"message": "请先登录",
			})
			context.Abort()
			return
		}
		if claims.UserAgent != context.GetHeader("User-Agent") {
			context.JSON(401, gin.H{
				"message": "请勿在多个地方登录",
			})
			context.Abort()
			return
		}
		// 10秒刷新一下token
		now := time.Now()
		if claims.ExpiresAt.Sub(now) < time.Second*50 {
			claims.ExpiresAt = jwt.NewNumericDate(time.Now().Add(time.Minute))
			tokenStr, err := token.SignedString([]byte("dlfkhjkdlhjkdgh"))
			if err != nil {
				context.JSON(401, gin.H{
					"message": "请先登录",
				})
				context.Abort()
				return
			}
			context.Header("x-jwt-token", tokenStr)

		}

		context.Set(web.UserClaimsKey, claims)

	}
}
